#ifndef __mPoint__
#define __mPoint__

#define PI 3.1415926535897932385
#define TAU 6.2831853071795864769
#define DegToRad 0.017453293
#define RadToDeg 57.2957795
#include <cmath>

class mPoint
{
public:
    double x,y,z,a;

    mPoint() {};
    mPoint(double xi, double yi, double zi):x(xi),y(yi),z(zi){}

    //OPERATORS
    mPoint operator - () const
    {
        return mPoint(-x,-y,-z);
    }
    mPoint operator - (const mPoint &v) const
    {
        return mPoint(x-v.x,y-v.y,z-v.z);
    }
    mPoint operator + (const mPoint &v) const
    {
        return mPoint(x+v.x,y+v.y,z+v.z);
    }

    mPoint operator * (const double &v) const
    {
        return mPoint( x*v , y*v ,z*v);
    }


    mPoint & operator += (const mPoint &v)
    {
        x+=v.x;
        y+=v.y;
        z+=v.z;
        return *this;
    }
    mPoint & operator -= (const mPoint &v)
    {
        x-=v.x;y-=v.y;z-=v.z;
        return *this;
    }
    mPoint & operator *= (const double v)
    {
        x*=v;
        y*=v;
        z*=v;
        return *this;
    }
    mPoint & operator *= (const mPoint &v)
    {
        x*=v.x;
        y*=v.y;
        z*=v.z;
        return *this;
    }

    mPoint & operator /= (const mPoint &v)
    {
        x/=v.x;
        y/=v.y;
        z/=v.z;
        return *this;
    }


    //use as vector
    double len() const
    {
        return sqrt(x*x+y*y+z*z);
    }

    double lenSq() const
    {
        return x*x+y*y+z*z;
    }

    double dot(const mPoint &v) const
    {
        return x*v.x+y*v.y+z*v.z;
    }

    void normalize()
    {
        double lenght = len();
        if (!lenght)
            return;

        double div = 1.0/lenght;
        x *= div;
        y *= div;
        z *= div;
    }

    void positive()
    {
        if (x < 0) x = -x;
        if (y < 0) y = -y;
        if (z < 0) z = -z;
    }

    //Functions
    void SetValue(double,double,double);
    void SetValue(mPoint v);

    bool Match(mPoint, double maxRelativeError=0.001);

    //Transform current value;
    void RotateXY(double);
    void SetCCWCircleCenter(mPoint,mPoint,double r);
    void SetCWCircleCenter(mPoint,mPoint,double r);

    //new Vertexfrom old
    mPoint Rotate(double);

    //mPoint RotateX(double);
    void RotateY(double);
    void RotateX(double);

    mPoint RotateY_out(double);
    mPoint RotateX_out(double);


    mPoint Translate(mPoint);

    mPoint GetFromPoint(double radiaani,double lenght);
    mPoint GetMidPoint(mPoint,double paikka=0.5);

    //GET Bezier point
    double GetAngleDiff(mPoint p2,mPoint p3); //Get Angle Difference
    double GetDistanceXY(mPoint);
    double GetDistanceXYZ(mPoint);
    double GetDirectionXY(mPoint);
};
//Global functions
mPoint mP(double,double,double z=0);

#endif // __mPoint__
